<?php

namespace Biz\service\activity\project;

use Biz\model\activity\BizProjectCategoryModel;
use Biz\model\activity\BizProjectCustomerModel;
use Biz\model\activity\BizProjectGroupModel;
use Biz\model\activity\BizProjectPRelationIdsModel;
use Biz\model\activity\BizProjectPrepareModel;
use Biz\model\activity\BizProjectPrepareModelRecord;
use Biz\model\activity\BizProjectResponsibilityModel;
use Doraemon\model\Admin\BeerUsUser;
use Doraemon\tools\Log;
use Encore\Admin\Grid;
use Encore\Admin\Widgets\Form;
use Exception;
use Hhz\AdministrativeRegion\Region;

class BizProjectPrepare extends BizProjectPageTpl
{


    const TPL_CONFIG_TPL_NAME = '售前项目';
    const INTRO_PROCESS_MAP = [
        '跟进中20%', '跟进中50%', '跟进中80%', '需求流失', '已下单',
    ];

    const CHANGE_CONTENT = [
        1 => '均不需要', 2 => '策划方案', 3 => '媒介报价', 4 => '策划方案与媒介报价',
    ];
    const PLAN_CHANGE_MAP = [
        '无变化', '较大变化', '较小变化',
    ];

    public function exportDisplay()
    {
        $resource = $this->getExportList();
        $header = [
            'id', '创建时间',
            '销售', '策划', '媒介',
            '品牌名称', '合作品类', '合作产品', '项目名称', '预算', '需求简述', '项目进度', '状态注释',
            '方案累计版本数', '需求变化程度', '媒介首次提报金额', '媒介末次提报金额', '媒介报价修改次数',
        ];
        //权限
        $fieldAuth = BizProjectGroup::fieldAuth($this->adminId());
        list($responsible, $base, $intro, $plan, $offer) = $this->extract($fieldAuth['pre'] ?? []);

        $instance = \Biz\service\activity\project\ExportToolsBizProject::getInstance();
        $list = [$header];
        $customerName = BizProjectCustomerModel::adminNameOptions();
        foreach ($resource as $k => $v) {
            //数据开始拼接
            $temp = [
                $v['id'],
                $v['created_at'],
            ];

            //项目责任方
            $tempResponsible = $this->exportField($responsible) ? [
                implode(',', $v['seller']),
                implode(',', $v['planner']),
                implode(',', $v['medium']),
            ] : array_fill(0, 3, '');
            $temp = array_merge($temp, $tempResponsible);
            //客户信息
            $tempInfo = $this->exportField($base) ? [
                $this->useNameOptions($v['project_customer_name'], $customerName),
                implode(',', $v['project_category']),
                $v['project_product'],
                $v['project_name'],
                $v['project_budget'],
            ] : array_fill(0, 5, '');
            $temp = array_merge($temp, $tempInfo);
            //项目简述及状态
            $tempIntro = $this->exportField($intro) ? [
                $v['intro_reason'],
                $this->useNameOptions($v['intro_process'], self::INTRO_PROCESS_MAP),
                $v['intro_process_note'],
            ] : array_fill(0, 3, '');
            $temp = array_merge($temp, $tempIntro);
            //策划方案
            $tempPlan = $this->exportField($plan) ? [
                $v['plan_version'],
                $this->useNameOptions($v['plan_change'], self::PLAN_CHANGE_MAP),
            ] : array_fill(0, 2, '');
            $temp = array_merge($temp, $tempPlan);
            //媒介报价
            $tempOffer = $this->exportField($offer) ? [
                $v['offer_initial'],
                $v['offer_last'],
                $v['offer_times'],
            ] : array_fill(0, 3, '');
            $temp = array_merge($temp, $tempOffer);
            $list[] = $temp;
        }
        $instance::create(date("YmdHis") . '商业项目列表', $list);
    }

    public function condition(): array
    {
        $request = $this->getRequest();
        $created_at_start_date = $request->input('created_at.start');
        $created_at_end_date = $request->input('created_at.end');
        $seller = $request->input('seller');
        $planer = $request->input('planer');
        $medium = $request->input('medium');
        $project_customer_name = $request->input('project_customer_name');
        $project_category = $request->input('project_category');
        $project_name = $request->input('project_name');
        $intro_process = $request->input('intro_process');

        //参数转换成查询条件
        $condition = [];
        if ($created_at_start_date && $created_at_end_date) {
            $condition['created_at[<>]'] = [$created_at_start_date, $created_at_end_date];
        } elseif ($created_at_start_date) {
            $condition['created_at[>=]'] = $created_at_start_date;
        } elseif ($created_at_end_date) {
            $condition['created_at[<=]'] = $created_at_end_date;
        }
        $findError = false;
        $findIds = [];
        foreach ([$seller, $planer, $medium] as $i => $find) {
            if ($find) {
                $types = [
                    BizProjectResponsibilityModel::RESPONSIBILITY_TYPE_SELLER,
                    BizProjectResponsibilityModel::RESPONSIBILITY_TYPE_PLANNER,
                    BizProjectResponsibilityModel::RESPONSIBILITY_TYPE_MEDIUM,
                ];
                BizProjectResponsibilityModel::findProjectByAdmin($find, BizProjectResponsibilityModel::RESPONSIBILITY_MODULE_PREPARE, $types[$i]);
                $findProject = BizProjectResponsibilityModel::afterFindProject();
                if ($findProject) {
                    $findIds = empty($findIds) ? $findProject : array_intersect($findProject, $findIds);
                } else {
                    $findError = true;
                    break;
                }
            }
        }
        if ($project_customer_name) $condition['project_customer_name'] = $project_customer_name;
        if ($project_category) {
            $findProject = BizProjectPRelationIdsModel::findPrePid($project_category);
            if ($findProject) {
                $findIds = empty($findIds) ? $findProject : array_intersect($findProject, $findIds);
            } else {
                $findError = true;
            }
        }
        if ($findError) return ['id' => 0];
        if ($findIds) $condition['id'] = array_values($findIds);
        if ($project_name) $condition['project_name[~]'] = $project_name;
        if ($intro_process) $condition['intro_process'] = $intro_process;

        return $condition;
    }

    public function withInfoHtml(): array
    {
        $list = BizProjectPrepareModel::getAdmList($this->getRequestCondition());
        $project_budget = 0;
        $offer_initial = 0;
        $offer_last = 0;
        $order_number = $order_money = $process_number = $process_money = $abandon_number = $abandon_money = 0;
        foreach ($list as $v) {
            if (is_numeric($v['project_budget'])) $project_budget = bcadd($project_budget, $v['project_budget']);
            if (is_numeric($v['offer_initial'])) $offer_initial = bcadd($offer_initial, $v['offer_initial']);
            if (is_numeric($v['offer_last'])) $offer_last = bcadd($offer_last, $v['offer_last']);
            // 已下单项目数量
            if ($v['intro_process'] == 4) $order_number = $order_number + 1;
            // 已下单项目金额
            if ($v['intro_process'] == 4) $order_money = bcadd($order_money, $v['offer_last']);
            // 跟进中项目数量
            if (in_array($v['intro_process'], [0, 1, 2])) $process_number = $process_number + 1;
            // 跟进中项目金额
            if (in_array($v['intro_process'], [0, 1, 2])) $process_money = bcadd($process_money, $v['offer_last']);
            // 已流失项目数量
            if ($v['intro_process'] == 3) $abandon_number = $abandon_number + 1;
            // 已流失项目金额
            if ($v['intro_process'] == 3) $abandon_money = bcadd($abandon_money, $v['project_budget']);
        }
        $html = [
            "项目预算总计: " . number_format($project_budget, 2),
            "首次提报金额总计: " . number_format($offer_initial, 2),
            "末次提报金额总计: " . number_format($offer_last, 2),
            "项目总数 : " . BizProjectPrepareModel::statusTotal($this->getRequestCondition()),
            "已下单项目数量 : " . $order_number,
            "已下单项目金额 : " . number_format($order_money, 2),
            "跟进中项目数量 : " . $process_number,
            "跟进中项目金额 : " . number_format($process_money, 2),
            "已流失项目数量 : " . $abandon_number,
            "已流失项目金额 : " . number_format($abandon_money, 2),
        ];
        return ["提示", implode("<br/>", $html)];
    }

    public function getList(): array
    {
        $condition = ['ORDER' => ['id' => 'DESC']] + $this->getLimitCondition() + $this->getRequestCondition();
        $list = BizProjectPrepareModel::getAdmList($condition);
        foreach ($list as &$v) {
            $v['project_budget'] = $v['project_budget'] ? number_format((float)$v['project_budget'], 2) : '';
            $v['offer_initial'] = $v['offer_initial'] ? number_format((float)$v['offer_initial'], 2) : '';
            $v['offer_last'] = $v['offer_last'] ? number_format((float)$v['offer_last'], 2) : '';
        }

        return $list;
    }

    public function getTotal(): int
    {
        return BizProjectPrepareModel::statusTotal($this->getRequestCondition());
    }

    public function getGrid(Grid $grid)
    {
        //条件处理
        $grid->filter(function (Grid\Filter $filter) {
            // 去掉默认的id过滤器
            $filter->disableIdFilter();
            $filter->column(1 / 2, function (Grid\Filter $filter) {
                $nameOptions = BeerUsUser::getNameByUsername();
                $filter->between('created_at', '创建时间')->datetime();
                $filter->equal('seller', '销售')->multipleSelect($nameOptions);
                $filter->equal('planer', '策划')->multipleSelect($nameOptions);
                $filter->equal('medium', '媒介')->multipleSelect($nameOptions);

            });
            $filter->column(1 / 2, function (Grid\Filter $filter) {
                $filter->equal('project_customer_name', '品牌名称')->multipleSelect(BizProjectCustomerModel::adminNameOptions());
                $filter->equal('project_category', '合作品类')->multipleSelect(BizProjectCategoryModel::adminNameOptions(['pid[!]' => 0]));
                $filter->equal('project_name', '项目名称');
                $filter->equal('intro_process', '项目进度')->multipleSelect(BizProjectPrepare::INTRO_PROCESS_MAP);
            });
            if ($this->getRequestCondition()) $filter->expand();
        });
        //工具栏
        $grid->tools(function (Grid\Tools $tool) {
            $this->genExportButton($tool);
        });
        //列表显示
        $grid->column('id', 'ID');
        $grid->column('created_at_date', '创建时间');
        //权限显示
        $fieldAuth = BizProjectGroup::fieldAuth($this->adminId());

        list($responsible, $base, $intro, $plan, $offer) = $this->extract($fieldAuth['pre'] ?? []);
        if ($this->displayForm($responsible)) {
            $grid->column('seller', '销售')->label();
            $grid->column('planner', '策划')->label();
            $grid->column('medium', '媒介')->label();
        }
        if ($this->displayForm($base)) {
            $grid->column('project_customer_name', '品牌名称')->using(BizProjectCustomerModel::adminNameOptions());
            $grid->column('project_category', '合作品类')->label('warning');
            $grid->column('project_product', '合作产品');
            $grid->column('project_name', '项目名称');
            $grid->column('project_budget', '预算')->editable();
        }
        if ($this->displayForm($intro)) {
//            $grid->column('intro_reason', '需求简述')->editable();
            $grid->column('intro_process', '项目进度')->radio(BizProjectPrepare::INTRO_PROCESS_MAP);
//            $grid->column('intro_process_note', '状态注释')->editable();
        }
//        if ($this->displayForm($plan)) {
//            $grid->column('plan_version', '方案累计版本数');
//            $grid->column('plan_change', '需求变化程度')->radio(BizProjectPrepare::PLAN_CHANGE_MAP);
//        }
//        if ($this->displayForm($offer)) {
//            $grid->column('offer_initial', '媒介首次提报金额')->editable();
//            $grid->column('offer_last', '媒介末次提报金额')->editable();
//            $grid->column('offer_times', '媒介报价修改次数');
//        }
        $grid->fixColumns(1);
        $grid->actions(function (Grid\Displayers\Actions $actions) {
            //复制功能
            $copyUrl = BizProjectProject::getRoute()->getCreateRoute(0, ['pre_id' => $actions->row->id]);
            $actions->append('<a class="fa fa-copy" href="' . admin_url($copyUrl) . '">去创建项目</a>');
        });
    }
    
    public function getForm(Form $form)
    {
        $form->confirm('确定提交吗？');
        $nameOptions = BeerUsUser::getActiveNameByIds();
        $fieldAuth = BizProjectGroup::fieldAuth($this->adminId(), $this->isCreate());
        list($responsible, $base, $intro, $plan, $offer) = $this->extract($fieldAuth['pre'] ?? []);

        if ($this->displayGroupField($responsible)) {
            $form->fieldset("项目责任方", function (Form $form) use ($nameOptions, $responsible) {
                if ($this->displayForm($responsible)) $this->disableForm($form->multipleSelect('responsible.seller', '销售')->options($nameOptions)->default([$this->adminId()])->required(), $responsible);
                if ($this->displayForm($responsible)) $this->disableForm($form->multipleSelect('responsible.planner', '策划')->options($nameOptions), $responsible);
                if ($this->displayForm($responsible)) $this->disableForm($form->multipleSelect('responsible.medium', '媒介')->options($nameOptions), $responsible);
            });
        }
        if ($this->displayGroupField($base)) {
            $form->fieldset("客户信息", function (Form $form) use ($base) {
                $customerIds = BizProjectCustomer::findIds($this->adminId());
                if ($info = $this->formInfo()) {
                    $customerIds[] = $info['customer']['name'];
                }
                $customerNameOptions = $customerIds ? BizProjectCustomerModel::adminNameOptions(['id' => $customerIds]) : [];
                // 查看的人没有品牌名称的客户
                $responsibilityData = BizProjectCustomerModel::dataSelectInfo(['id' => $form->data()['project_customer_name']]);
                $customerNameOptions[$form->data()['project_customer_name']] = $responsibilityData['name'];
                $formCustomerName = $form->select('project_customer_name', '品牌名称')->options($customerNameOptions)->help("选择品牌后，该项目会关联该品牌在客户服务档案中的信息，相关信息请在客户服务档案中更新")->required();
                $areaMap = Region::getAllAreaDetail();
                foreach ($customerNameOptions as $key => $value) {
                    $responsibilityDataForm = BizProjectCustomerModel::dataSelectInfo(['id' => $key]);
                    $formCustomerName->when($key, function (Form $form) use ($key, $areaMap, $responsibilityDataForm) {
                        $form->display('responsible.seller', '客户所属区域')->with(function () use ($responsibilityDataForm) {
                            return BizProjectProject::CUSTOMER_AREA_MAP[$responsibilityDataForm['customer_area']];
                        })->disable()->help('与品牌关联，不允许修改');
                        $form->display('responsible.seller', '客户地理位置')->with(function () use ($responsibilityDataForm, $areaMap) {
                            return $areaMap[$responsibilityDataForm['customer_area_code']];
                        })->disable()->help('与品牌关联，不允许修改');;
                        $form->display('responsible.seller', '客户基础信息')->with(function () use ($responsibilityDataForm) {
                            return $responsibilityDataForm['customer_intro'];
                        })->disable()->help('与品牌关联，不允许修改');;
                        $form->display('responsible.seller', '客户特征')->with(function () use ($responsibilityDataForm) {
                            return $responsibilityDataForm['customer_features'];
                        })->required()->disable()->help('与品牌关联，不允许修改');;
                    });
                }

                if ($this->displayForm($base)) $this->disableForm($formCustomerName, $base);
                if ($this->displayForm($base)) $this->disableForm($form->radio('customer_type', '客户类型')->options(BizProjectProject::CUSTOMER_TYPE_MAP)->default(-1), $base);
                if ($this->displayForm($base)) $this->disableForm($form->select('customer_level', '客户分级')->options(BizProjectProject::CUSTOMER_LEVEL_MAP)->default(-1), $base);


                if ($this->displayForm($base)) $this->disableForm($form->multipleSelect('project_category', '合作品类')->options(BizProjectCategoryModel::adminNameLevelOptions())->required(), $base);
                if ($this->displayForm($base)) $this->disableForm($form->text('project_product', '合作产品')->placeholder('填写具体合作产品名称')->required(), $base);
                if ($this->displayForm($base)) $this->disableForm($form->text('project_name', '项目名称')->required(), $base);
                if ($this->displayForm($base)) $this->disableForm($form->text('project_budget', '预算')->help('仅数字')->required(), $base);
                if ($this->displayForm($base)) $this->disableForm($form->html($form->data()['budget']), $base);
            });
        }
        if ($this->displayGroupField($intro)) {
            $form->fieldset("项目简述及状态", function (Form $form) use ($intro) {
                if ($this->displayForm($intro)) $this->disableForm($form->textarea('intro_reason', '需求简述')->placeholder("请填写：1.主要产品，2.项目传播目的，3.客户需求概述，4.建议营销形式 等信息")->required()->attribute('maxlength', '500'), $intro);
                if ($this->displayForm($intro)) $this->disableForm($form->html($form->data()['reason']), $intro);
                if ($this->displayForm($intro)) $this->disableForm($form->radio('intro_process', '项目进度')->options(BizProjectPrepare::INTRO_PROCESS_MAP)->default(-1)->required(), $intro);
                if ($this->displayForm($intro)) $this->disableForm($form->textarea('intro_process_note', '状态注释')->help("请描写进度或原因")->required()->attribute('maxlength', '500'), $intro);
                if ($this->displayForm($intro)) $this->disableForm($form->radio('change_content', '本次需增加或修改内容')->options(BizProjectPrepare::CHANGE_CONTENT)->default(0)->required(), $intro);

            });
        }
        if ($this->displayGroupField($plan)) {
            $form->fieldset("策划方案", function (Form $form) use ($plan) {
                if ($this->displayForm($plan)) $this->disableForm($form->text('plan_version', '方案累计版本数')->default(0)->disable(), $plan);
                if ($this->displayForm($plan)) $this->disableForm($form->radio('plan_change', '需求变化程度')->options(BizProjectPrepare::PLAN_CHANGE_MAP), $plan);
            });
        }
        if ($this->displayGroupField($offer)) {
            $form->fieldset('媒介报价', function (Form $form) use ($offer) {
                if ($this->displayForm($offer)) $this->disableForm($form->text('offer_initial', '媒介首次提报金额')->help('仅数字'), $offer);
                if ($this->displayForm($offer)) $this->disableForm($form->text('offer_last', '媒介末次提报金额')->help('仅数字'), $offer);
                if ($this->displayForm($offer)) $this->disableForm($form->text('offer_times', '媒介报价修改次数')->default(0)->disable(), $offer);
            });
        }
        $form->fieldset('备注', function (Form $form) use ($offer) {
            $form->text('intro_link', '附件链接')->help('请输入链接');
        });
    }

    public function getFormInfo($id): array
    {
        $data = BizProjectPrepareModel::getAdmInfo($id);
        $data['change_content'] = -1;
        return $data;
    }

    /**
     * @throws Exception
     */
    public function save($input)
    {
        $id = $input['id'] ?? 0;
        $responsibleRequest = $input['responsible'] ?? [];
        $project_customer_name = $input['project_customer_name'] ?? 0;
        $project_category = BizProjectPrepareModel::formatMultiParam($input['project_category'] ?? []);
        $project_product = $input['project_product'] ?? '';
        $project_name = $input['project_name'] ?? '';
        $project_budget = $input['project_budget'] ?? '';
        $intro_reason = $input['intro_reason'] ?? '';
        $intro_link = $input['intro_link'] ?? '';
        $intro_process = $input['intro_process'] ?? -1;
        $intro_process_note = $input['intro_process_note'] ?? '';
        $plan_version = $input['plan_version'] ?? 0;
        $plan_change = $input['plan_change'] ?? -1;
        $offer_initial = $input['offer_initial'] ?? '';
        $offer_last = $input['offer_last'] ?? '';
        $offer_times = $input['offer_times'] ?? 0;
        $change_content = $input['change_content'] ?? 0;
        $customer_type = $input['customer_type'] ?? '';
        $customer_level = $input['customer_level'] ?? '';
        //validate
        $this->validateNumeric($offer_initial, '媒介首次提报金额仅能填数字');
        $this->validateNumeric($offer_last, '媒介末次提报金额仅能填数字');
        $this->validateNumeric($project_budget, '预算金额仅能填数字, 15w=>150000');
        //构造 db 存储结构
        $request = compact('project_customer_name',
            'project_category',
            'project_product',
            'project_name',
            'project_budget',
            'intro_reason',
            'intro_link',
            'intro_process',
            'intro_process_note',
            'plan_version',
            'plan_change',
            'offer_initial',
            'offer_last',
            'offer_times',
            'change_content',
            'customer_type',
            'customer_level'
        );
        $fieldAuth = BizProjectGroup::fieldAuth($this->adminId(), $id == 0);
        list($responsible, $base, $intro, $plan, $offer) = $this->extract($fieldAuth['pre'] ?? []);


        //项目责任方
        if (!$this->saveForm($responsible)) {
            $responsibleRequest = [];
        }
        //客户信息
        if (!$this->saveForm($base)) {
            unset($request['change_content'], $request['project_category'], $request['project_name'], $request['project_customer_name'], $request['project_product'], $request['project_budget']);
        }
        //项目简述及状态
        if (!$this->saveForm($intro)) {
            unset($request['intro_reason'], $request['intro_process'], $request['intro_process_note']);
        }
        //策划方案
        if (!$this->saveForm($plan)) {
            unset($request['plan_version'], $request['plan_change']);
        }
        //媒介报价
        if (!$this->saveForm($offer)) {
            unset($request['offer_initial'], $request['offer_last'], $request['offer_times']);
        }


        //查询旧的数据
        $exists = BizProjectResponsibilityModel::normalList($id, BizProjectResponsibilityModel::RESPONSIBILITY_MODULE_PREPARE);
        $existsResponsibleMap = [];
        $existsMap = [];
        if ($exists) {
            foreach ($exists as $v) {
                $existsMap[$v['type']][$v['admin_id']] = $v;
                if (BizProjectResponsibilityModel::isNormal($v['status'])) {
                    $existsResponsibleMap[BizProjectResponsibilityModel::RESPONSIBILITY_TYPE_NAME_MAP[$v['type']]][$v['admin_id']] = $v['admin_id'];
                }
            }
        }
        $info = $id ? BizProjectPrepareModel::dataSelectInfo(['id' => $id]) : [];
        if ($id) {
            $info['project_category'] = implode(',', BizProjectPRelationIdsModel::getPreRelationIds($info['id']));
            if ($request['change_content'] == BizProjectPrepareModel::CHANGE_CONTENT_2) {
                $request['plan_version'] = $info['plan_version'] + 1;
                $request['offer_times'] = $info['offer_times'];
            }
            if ($request['change_content'] == BizProjectPrepareModel::CHANGE_CONTENT_3) {
                $request['plan_version'] = $info['plan_version'];
                $request['offer_times'] = $info['offer_times'] + 1;
            }
            if ($request['change_content'] == BizProjectPrepareModel::CHANGE_CONTENT_4) {
                $request['plan_version'] = $info['plan_version'] + 1;
                $request['offer_times'] = $info['offer_times'] + 1;
            }
            if ($request['change_content'] == BizProjectPrepareModel::CHANGE_CONTENT_1) {
                $request['plan_version'] = $info['plan_version'];
                $request['offer_times'] = $info['offer_times'];
            }
        } else {
            // 新增的时候媒介报价还是0
            if ($request['change_content'] == BizProjectPrepareModel::CHANGE_CONTENT_2) {
                $request['plan_version'] = 1;
                $request['offer_times'] = 0;
            }
            if ($request['change_content'] == BizProjectPrepareModel::CHANGE_CONTENT_3) {
                $request['plan_version'] = 0;
                $request['offer_times'] = 0;
            }
            if ($request['change_content'] == BizProjectPrepareModel::CHANGE_CONTENT_4) {
                $request['plan_version'] = 1;
                $request['offer_times'] = 0;
            }
        }
        list($project_id, $responsibleChange) = BizProjectPrepareModel::action(function () use ($id, $request, $responsibleRequest, $existsMap, $info) {
            $responsibleChange = false;
            $project_id = 0;
            $response = [
                &$project_id,
                &$responsibleChange,
            ];
            $condition = $id ? ['id' => $id] : [];
            $project_category = $request['project_category'] ?? null;
            unset($request['project_category']);
            //主表入库操作
            $rs = $request ? BizProjectPrepareModel::addData($request + $condition) : true;
            $newPreId = BizProjectPrepareModel::id();
            // 如果是新增直接插入记录
            if ($id) {
                // 判断新值和旧值是否一致
                if ($info['intro_reason'] != $request['intro_reason']) {
                    $record['type'] = BizProjectPrepareModelRecord::TYPE_1;
                    $record['admin'] = $this->adminId();
                    $record['record'] = $request['intro_reason'];
                    $record['pre_id'] = $id;
                    BizProjectPrepareModelRecord::addData($record);
                }
                if ($info['project_budget'] != $request['project_budget']) {
                    $record['type'] = BizProjectPrepareModelRecord::TYPE_2;
                    $record['admin'] = $this->adminId();
                    $record['record'] = $request['project_budget'];
                    $record['pre_id'] = $id;
                    BizProjectPrepareModelRecord::addData($record);
                }

            } else {
                // 直接插入
                if (!empty($request['project_budget'])) {
                    $record['type'] = BizProjectPrepareModelRecord::TYPE_2;
                    $record['admin'] = $this->adminId();
                    $record['record'] = $request['project_budget'];
                    $record['pre_id'] = $newPreId;
                    BizProjectPrepareModelRecord::addData($record);
                }
                if (!empty($request['intro_reason'])) {
                    $record['type'] = BizProjectPrepareModelRecord::TYPE_1;
                    $record['admin'] = $this->adminId();
                    $record['record'] = $request['intro_reason'];
                    $record['pre_id'] = $newPreId;
                    BizProjectPrepareModelRecord::addData($record);
                }
            }
            if (!$rs) throw new Exception('售前项目主表保存失败');
            $project_id = $id ?: $newPreId;
            if (empty($project_id)) throw new Exception('获取id失败');
            //合作品类存储
            if ($project_category) {
                BizProjectPRelationIdsModel::savePreRelationIds($project_id, $project_category);
            }

            if (empty($responsibleRequest)) return $response;
            //项目责任方需要参数初始化
            $rows = [];
            $map = [];
            if (isset($responsibleRequest['seller'])) $map[BizProjectResponsibilityModel::RESPONSIBILITY_TYPE_SELLER] = $responsibleRequest['seller'];
            if (isset($responsibleRequest['planner'])) $map[BizProjectResponsibilityModel::RESPONSIBILITY_TYPE_PLANNER] = $responsibleRequest['planner'];
            if (isset($responsibleRequest['medium'])) $map[BizProjectResponsibilityModel::RESPONSIBILITY_TYPE_MEDIUM] = $responsibleRequest['medium'];


            foreach ($map as $key => $v) {
                $find = $existsMap[$key] ?? [];
                $arr = [];
                if (!empty($v)) {
                    $arr = is_string($v) ? explode(',', $v) : $v;
                }
                //开始处理每个用户的归属
                foreach ($arr as $admin_id) {
                    if (empty($admin_id)) continue;
                    //处理已经存在的数据
                    if (isset($find[$admin_id])) {
                        $status = $find[$admin_id]['status'];
                        if (!BizProjectResponsibilityModel::isNormal($status)) {
                            //恢复记录状态
                            $rows[] = ['id' => $find[$admin_id]['id'], 'status' => BizProjectResponsibilityModel::normalStatus()];
                            $responsibleChange = false;
                        }
                        unset($find[$admin_id]);
                    } else {
                        //新增记录
                        $rows[] = ['project_id' => $project_id, 'type' => $key, 'admin_id' => $admin_id, 'module' => BizProjectResponsibilityModel::RESPONSIBILITY_MODULE_PREPARE];
                        $responsibleChange = true;
                    }
                }
                //删除没有处理的
                foreach ($find as $item) {
                    $rows[] = ['id' => $item['id'], 'status' => BizProjectResponsibilityModel::delStatus()];
                    $responsibleChange = true;
                }
            }

            foreach ($rows as $row) {
                BizProjectResponsibilityModel::addData($row);
            }
            return $response;
        });
        try {
            //项目创建成功发送邮件
            $this->makeEmailNotice($request,$info,$responsibleRequest, $existsResponsibleMap, $project_id, $responsibleChange);
        } catch (Exception $e) {
            throw new Exception('项目创建成功,发送邮件失败:' . $e->getMessage() . " line:". $e->getLine() . " file:" . $e->getFile());
        }
    }

    public function delete($id)
    {
        //'admin.pre_delete' => '售前项目-删除',
        $fieldAuth = BizProjectGroup::fieldAuth($this->adminId(), 'admin');
        if (!$this->exportField($fieldAuth['pre_delete'])) throw new Exception("权限不足");
        return BizProjectPrepareModel::statusDelete($id);
    }

    /**
     * @throws Exception
     */
    public function put($input, $id)
    {
        $name = $input['name'] ?? '';
        $value = $input['value'] ?? '';
        $id = $input['pk'] ?? $id;
        $data = [];
        if (isset($input['intro_process'])) {
            $data['intro_process'] = $input['intro_process'];
        }
        if (isset($input['plan_change'])) {
            $data['plan_change'] = $input['plan_change'];
        }
        //editable 字段处理
        switch ($name) {
            case 'project_budget':
                $value = str_replace(",", "", $value);
                break;
            case 'intro_reason':
            case 'intro_process_note':
                break;
            case 'plan_version':
                $this->validatePositiveInt($value, '方案累计版本数是大于等于 0 的整数');
                break;
            case 'offer_initial':
                $value = str_replace(",", "", $value);
                $this->validateNumeric($value, '媒介首次提报金额仅能填数字');
                break;
            case 'offer_last':
                $value = str_replace(",", "", $value);
                $this->validateNumeric($value, '媒介末次提报金额仅能填数字');
                break;
            case 'offer_times':
                $this->validatePositiveInt($value, '媒介报价修改次数是大于等于 0 的整数');
                break;
        }


        if ($name) $data[$name] = $value;
        if (empty($data)) throw new \Exception('未定义的快速更新字段');
        if ($id) {
            //查询旧的数据
            $exists = BizProjectResponsibilityModel::existsList($id, BizProjectResponsibilityModel::RESPONSIBILITY_MODULE_PREPARE);
            $existsResponsibleMap = [];
            if ($exists) {
                foreach ($exists as $v) {
                    if (BizProjectResponsibilityModel::isNormal($v['status'])) {
                        $existsResponsibleMap[BizProjectResponsibilityModel::RESPONSIBILITY_TYPE_NAME_MAP[$v['type']]][$v['admin_id']] = $v['admin_id'];
                    }
                }
            }
            $info = BizProjectPrepareModel::dataSelectInfo(['id' => $id]);
            $this->makeEmailNotice($data, $info, $responsibleRequest = [], $existsResponsibleMap, $id, $responsibleChange = false);
            $data['id'] = $id;
            BizProjectPrepareModel::addData($data);
        }
    }


    public function extract($fieldAuth): array
    {
        $responsible = $fieldAuth['responsible'] ?? 0;
        $base = $fieldAuth['base'] ?? 0;
        $intro = $fieldAuth['intro'] ?? 0;
        $plan = $fieldAuth['plan'] ?? 0;
        $offer = $fieldAuth['offer'] ?? 0;
        return [$responsible, $base, $intro, $plan, $offer];
    }

    private function makeEmailNotice($request, $info, $responsibleRequest, $existsResponsibleMap, $project_id, $responsibleChange)
    {
        //如果存在旧的记录, 追加至提交的记录
        $request += $responsibleRequest;
        $isCreate = true;
        if ($info) {
            $request += [
                'seller' => $existsResponsibleMap['seller'] ?? [],
                'planner' => $existsResponsibleMap['planner'] ?? [],
                'medium' => $existsResponsibleMap['medium'] ?? [],
            ];
            $request += $info;
            $isCreate = false;
        }
        //最终的责任方数据
        $seller = $responsibleRequest['seller'] ?? ($existsResponsibleMap['seller'] ?? []);
        $planner = $responsible['planner'] ?? ($existsResponsibleMap['planner'] ?? []);
        $medium = $responsible['medium'] ?? ($existsResponsibleMap['medium'] ?? []);
        $seller = $this->filterArrayParam($seller);
        $planner = $this->filterArrayParam($planner);
        $medium = $this->filterArrayParam($medium);
        $sendResponsibleChange = false;
        $sendResponsibleAdmin = [];
        if ($responsibleRequest) {
            foreach ($responsibleRequest as $key => $admins) {
                if ($key == 'planner' || $key == 'medium') {
                    $admins = $this->filterArrayParam($admins);
                    $diff = array_diff($admins, $$key);
                    if ($diff) {
                        $sendResponsibleChange = true;
                        $sendResponsibleAdmin = array_merge($sendResponsibleAdmin, $diff);
                    }

                }
            }
        }

        //查询用户信息
        BeerUsUser::searchId($this->adminId());
        BeerUsUser::searchId($seller);
        BeerUsUser::searchId($planner);
        BeerUsUser::searchId($medium);
        $admin = BeerUsUser::afterGetRowsMap($this->adminId());
        //初始化邮件必要的参数
        $this->emailNotice['_admin'] = $admin;
        $this->emailNotice['_seller'] = $seller;
        $this->emailNotice['_planner'] = $planner;
        $this->emailNotice['_medium'] = $medium;
        $this->emailNotice['_send_admin'] = $sendResponsibleAdmin;
        $this->emailNotice['_project_name'] = $request['project_name'] ?? '';
        $this->emailNotice['_link'] = admin_url(BizProjectPrepare::getRoute()->getEditRoute($project_id));

        $customerName = BizProjectCustomerModel::adminNameOptions();
        $projectCategory = BizProjectCategoryModel::adminNameOptions(['pid[!]' => 0]);

        $projectMap = [
            ['project_customer_name', '品牌名称：' . $this->useNameOptions($request['project_customer_name'], $customerName)],
            ['project_category', '合作品类：' . $this->useNameOptions($request['project_category'], $projectCategory)],
            ['project_product', '合作产品：' . $request['project_product']],
            ['project_name', '项目名称：' . $request['project_name']],
            ['project_budget', '预算：' . $request['project_budget']],
            ['intro_reason', '需求简述：' . $request['intro_reason']],
            ['intro_process', '项目进度：' . self::INTRO_PROCESS_MAP[$request['intro_process'] ?? '']],
            ['intro_process_note', '状态注释：' . $request['intro_process_note']],
            ['change_content', '本次需增加或修改内容：' . BizProjectPrepare::CHANGE_CONTENT[$request['change_content']]],
        ];
        $responsibleMap = [
            ['responsible_seller', '销售：' . implode(',', BeerUsUser::afterGetRowsMap($seller))],
            ['responsible_planner', '策划：' . implode(',', BeerUsUser::afterGetRowsMap($planner))],
            ['responsible_medium', '媒介：' . implode(',', BeerUsUser::afterGetRowsMap($medium))],
        ];
        $infoMap = [
            ['project_customer_name', '品牌名称：' . $this->useNameOptions($request['project_customer_name'], $customerName)],
            ['project_category', '合作品类：' . $this->useNameOptions($request['project_category'], $projectCategory)],
            ['project_product', '合作产品：' . $request['project_product']],
            ['project_name', '项目名称：' . $request['project_name']],
            ['project_budget', '预算：' . $request['project_budget']],
        ];
        $processMap = [
            ['intro_reason', '需求简述：' . $request['intro_reason']],
            ['intro_process', '项目进度：' . self::INTRO_PROCESS_MAP[$request['intro_process'] ?? '']],
            ['intro_process_note', '状态注释：' . $request['intro_process_note']],
            ['change_content', '本次需增加或修改内容：' . BizProjectPrepare::CHANGE_CONTENT[$request['change_content']]],

        ];
//        $requestMap = [
//            ['plan_version', '方案累计版本数：'. $request['plan_version']],
//            ['plan_change', '需求变化程度：'. self::PLAN_CHANGE_MAP[$request['plan_change'] ?? '']],
//        ];
        $cashMap = [
            ['offer_initial', '媒介首次提报金额：' . $request['offer_initial']],
            ['offer_last', '媒介末次提报金额：' . $request['offer_last']],
            ['offer_times', '媒介报价修改次数：' . $request['offer_times']],
        ];

        //新建时
        $this->changeCheck($projectMap, $request, $info);
        if ($isCreate) $this->sendCreateMail();
        //项目责任方有新增或变动
        $this->changeCheck($responsibleMap, $request, $info);
        if ($sendResponsibleChange) $this->sendResponsibleChangeMail();
        //策划、媒介这两个字段有变动
        if ($responsibleChange && !$isCreate) $this->sendResponsibleChangeFieldMail();
        //品牌名称、合作品类、合作产品、项目名称、预算有变动
        if ($this->changeCheck($infoMap, $request, $info)) $this->sendInfoMail();
        //需求简述、项目进度、状态注释有变动
        if ($this->changeCheck($processMap, $request, $info)) $this->sendProcessMail();
        //方案累计版本数、需求变化程度有变动
        //if ($this->changeCheck($requestMap, $request, $info)) $this->sendRequestMail();
        //媒介首次提报金额、媒介末次提报金额、媒介报价修改次数有变动
        if ($this->changeCheck($cashMap, $request, $info)) $this->sendCashMail();
    }

    private function sendCreateMail()
    {
        $title = "【售前项目】{$this->emailNotice['_project_name']}";
        $header = <<<EMAIL
<br/>{$this->emailNotice['_admin']} 创建了一个新的售前项目，请及时分配跟进人
EMAIL;
        $body = <<<BODY
<br/>
<br/>{$this->emailNotice['project_customer_name']}
<br/>{$this->emailNotice['project_category']}
<br/>{$this->emailNotice['project_product']}
<br/>{$this->emailNotice['project_name']}
<br/>{$this->emailNotice['project_budget']}
<br/>{$this->emailNotice['intro_reason']}
<br/>{$this->emailNotice['intro_process']}
<br/>{$this->emailNotice['intro_process_note']}
<br/>{$this->emailNotice['change_content']}
<br/>
<br/>项目链接：<a target="_blank" href="{$this->emailNotice['_link']}">{$this->emailNotice['_link']}</a>
BODY;

        $emails = $this->getLeaderEmailByUser($this->emailNotice['_seller'], false);
        //媒介组组长，策划组组长、pm组组长
        $leaders = $this->getLeaderEmail([BizProjectResponsibilityModel::RESPONSIBILITY_TYPE_PM, BizProjectResponsibilityModel::RESPONSIBILITY_TYPE_MEDIUM, BizProjectResponsibilityModel::RESPONSIBILITY_TYPE_PLANNER], false);
        $emails = array_merge($emails, $leaders);
        Log::info('记录sendCreateMail', [$emails, $title, $header . $body]);
        $this->sendMail($emails, $title, $header . $body);
    }

    private function sendResponsibleChangeMail()
    {
        $title = "【售前项目】{$this->emailNotice['_project_name']}";
        $header = <<<EMAIL
<br/>您有一个新项目，请及时跟进
EMAIL;

        $body = <<<BODY
<br/>
<br/>{$this->emailNotice['responsible_seller']}
<br/>{$this->emailNotice['project_customer_name']}
<br/>{$this->emailNotice['project_category']}
<br/>{$this->emailNotice['project_product']}
<br/>{$this->emailNotice['project_name']}
<br/>{$this->emailNotice['project_budget']}
<br/>{$this->emailNotice['intro_reason']}
<br/>{$this->emailNotice['intro_process']}
<br/>{$this->emailNotice['intro_process_note']}
<br/>
<br/>项目链接：<a target="_blank" href="{$this->emailNotice['_link']}">{$this->emailNotice['_link']}</a>
BODY;

        $email = array_merge($this->emailNotice['_seller'], $this->emailNotice['_send_admin']);
        $emails = $this->email($email);
        //媒介组组长，策划组组长、pm组组长
        $leaders = $this->getLeaderEmail([BizProjectResponsibilityModel::RESPONSIBILITY_TYPE_SELLER, BizProjectResponsibilityModel::RESPONSIBILITY_TYPE_MEDIUM, BizProjectResponsibilityModel::RESPONSIBILITY_TYPE_PLANNER], false);
        $emails = array_merge($emails, $leaders);
        Log::info('记录sendResponsibleChangeMail', [$emails, $title, $header . $body]);
        $this->sendMail($emails, $title, $header . $body);
    }

    private function sendResponsibleChangeFieldMail()
    {
        $title = "【售前项目-项目责任方变更】{$this->emailNotice['_project_name']}";
        $header = <<<EMAIL
<br/>{$this->emailNotice['_admin']} 变更了项目责任方，请查看变更内容
EMAIL;

        $body = <<<BODY
<br/>
<br/>{$this->emailNotice['project_name']}
<br/>{$this->emailNotice['responsible_planner']}
<br/>{$this->emailNotice['responsible_medium']}
<br/>
<br/>项目链接：<a target="_blank" href="{$this->emailNotice['_link']}">{$this->emailNotice['_link']}</a>
BODY;

        $email = array_merge($this->emailNotice['_seller'], $this->emailNotice['_send_admin']);
        $emails = $this->email($email);
        $leaders = $this->getLeaderEmail([BizProjectResponsibilityModel::RESPONSIBILITY_TYPE_SELLER, BizProjectResponsibilityModel::RESPONSIBILITY_TYPE_MEDIUM, BizProjectResponsibilityModel::RESPONSIBILITY_TYPE_PLANNER], false);
        $emails = array_merge($emails, $leaders);
        Log::info('记录sendResponsibleChangeFieldMail', [$emails, $title, $header . $body]);
        $this->sendMail($emails, $title, $header . $body);
    }

    private function sendInfoMail()
    {
        $title = "【售前项目-客户信息变更】{$this->emailNotice['_project_name']}";
        $header = <<<EMAIL
<br/>{$this->emailNotice['_admin']} 变更了客户信息，请查看变更内容
EMAIL;
        $body = <<<BODY
<br/>
<br/>{$this->emailNotice['project_name']}
<br/>{$this->emailNotice['project_customer_name']}
<br/>{$this->emailNotice['project_category']}
<br/>{$this->emailNotice['project_product']}
<br/>{$this->emailNotice['project_budget']}
<br/>
<br/>项目链接：<a target="_blank" href="{$this->emailNotice['_link']}">{$this->emailNotice['_link']}</a>
BODY;

        $email = array_merge($this->emailNotice['_seller'], $this->emailNotice['_medium'], $this->emailNotice['_planner']);
        //媒介组组长，策划组组长、pm组组长
        $leaders = $this->getLeaderEmail([BizProjectResponsibilityModel::RESPONSIBILITY_TYPE_MEDIUM, BizProjectResponsibilityModel::RESPONSIBILITY_TYPE_PLANNER, BizProjectResponsibilityModel::RESPONSIBILITY_TYPE_SELLER], false);
        $emails = $this->email($email);
        $emails = array_merge($emails, $leaders);
        Log::info('记录sendInfoMail', [$emails, $title, $header . $body]);

        $this->sendMail($emails, $title, $header . $body);
    }

    private function sendProcessMail()
    {
        $title = "【售前项目-项目简述及状态变更】{$this->emailNotice['_project_name']}";
        $header = <<<EMAIL
<br/>{$this->emailNotice['_admin']} 变更了项目简述及状态，请查看变更内容
EMAIL;
        $body = <<<BODY
<br/>
<br/>{$this->emailNotice['project_name']}
<br/>{$this->emailNotice['intro_reason']}
<br/>{$this->emailNotice['intro_process']}
<br/>{$this->emailNotice['intro_process_note']}
<br/>{$this->emailNotice['change_content']}
<br/>
<br/>项目链接：<a target="_blank" href="{$this->emailNotice['_link']}">{$this->emailNotice['_link']}</a>
BODY;

        $email = array_merge($this->emailNotice['_planner'], $this->emailNotice['_medium']);
        //媒介组组长，策划组组长
        $leaders = $this->getLeaderEmail([BizProjectResponsibilityModel::RESPONSIBILITY_TYPE_MEDIUM, BizProjectResponsibilityModel::RESPONSIBILITY_TYPE_PLANNER, BizProjectResponsibilityModel::RESPONSIBILITY_TYPE_SELLER], false);
        $emails = $this->email($email);
        $emails = array_merge($emails, $leaders);
        Log::info('记录sendProcessMail', [$emails, $title, $header . $body]);

        $this->sendMail($emails, $title, $header . $body);
    }

    private function sendRequestMail()
    {
        $title = "【售前项目-策划方案变更】{$this->emailNotice['_project_name']}";
        $header = <<<EMAIL
<br/>{$this->emailNotice['_admin']} 变更了策划方案，请查看变更内容
EMAIL;
        $body = <<<BODY
<br/>
<br/>{$this->emailNotice['project_name']}
<br/>{$this->emailNotice['plan_version']}
<br/>{$this->emailNotice['plan_change']}
<br/>
<br/>项目链接：<a target="_blank" href="{$this->emailNotice['_link']}">{$this->emailNotice['_link']}</a>
BODY;

        $email = array_merge($this->emailNotice['_seller']);
        //策划组组长
        $leaders = $this->getLeaderEmail([BizProjectResponsibilityModel::RESPONSIBILITY_TYPE_PLANNER], false);
        $emails = $this->email($email);
        $emails = array_merge($emails, $leaders);
        Log::info('记录sendRequestMail', [$emails]);

        $this->sendMail($emails, $title, $header . $body);
    }
    private function sendCashMail()
    {
        $title = "【售前项目-媒介报价变更】{$this->emailNotice['_project_name']}";
        $header = <<<EMAIL
<br/>{$this->emailNotice['_admin']} 变更了媒介报价，请查看变更内容
EMAIL;
        $body = <<<BODY
<br/>
<br/>{$this->emailNotice['project_name']}
<br/>{$this->emailNotice['offer_initial']}
<br/>{$this->emailNotice['offer_last']}
<br/>{$this->emailNotice['offer_times']}
<br/>
<br/>项目链接：<a target="_blank" href="{$this->emailNotice['_link']}">{$this->emailNotice['_link']}</a>
BODY;

        $email = array_merge($this->emailNotice['_seller']);
        //策划组组长
        $leaders = $this->getLeaderEmail([BizProjectResponsibilityModel::RESPONSIBILITY_TYPE_MEDIUM], false);
        $emails = $this->email($email);
        $emails = array_merge($emails, $leaders);
        Log::info('记录sendCashMail', [$emails, $title, $header . $body]);

        $this->sendMail($emails, $title, $header . $body);
    }


}
